package com.east.config;

import com.east.config.handler.CustomAccessDeniedHandler;
import com.east.config.handler.CustomAuthenticationFailureHandler;
import com.east.config.handler.CustomAuthenticationSuccessHandler;
import com.east.config.filters.TokenFilter;
import com.east.config.handler.CustomLogoutSuccessHandler;
import com.east.utils.Constants;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class SecurityConfig {
    @Resource
    private CustomAuthenticationSuccessHandler authenticationSuccessHandler;
    @Resource
    private CustomAuthenticationFailureHandler authenticationFailureHandler;
    @Resource
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;
    @Resource
    private CustomAccessDeniedHandler customAccessDeniedHandler;
    @Resource
    private TokenFilter tokenFilter;

    /**
     * 指定密码加密方式
     *
     * @return
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * springSecurity的配置
     *
     * @param httpSecurity
     * @return
     * @throws Exception
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.formLogin(formLogin -> {
            formLogin.loginProcessingUrl(Constants.LOGIN_URI)
                    .usernameParameter("loginAct")
                    .passwordParameter("loginPwd")
                    .successHandler(authenticationSuccessHandler)  // 登陆成功后的执行器
                    .failureHandler(authenticationFailureHandler); // 登陆失败后的执行器
        });
        httpSecurity.authorizeHttpRequests((authorize) -> {
            authorize.requestMatchers("/api/login").permitAll()
                    .anyRequest()      // 所有请求都需要验证
                    .authenticated();   // 已验证的授予权限信息
        });
        httpSecurity.csrf(csrf -> csrf.disable());  // 关闭csrf
        httpSecurity.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);// 添加token过滤器
        httpSecurity.sessionManagement((session) -> { // 关闭session
            session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        });
        httpSecurity.logout((logout) -> {
            logout.logoutUrl(Constants.LOGOUT_URI)
                    .logoutSuccessHandler(customLogoutSuccessHandler);
        });
        httpSecurity.exceptionHandling(httpSecurityExceptionHandlingConfigurer -> {
            httpSecurityExceptionHandlingConfigurer.accessDeniedHandler(customAccessDeniedHandler);
        });
        return httpSecurity.build();
    }
}
